상속(Inheritance)
✒️ 2025-05-26 18:24 내용 수정
실제 부모가 자식에게 무언가를 물려주는 것처럼, Java에서 부모 역할의 클래스가 자식 역할의 클래스에게 모든 필드와 메서드를 물려주는 것
-
클래스(Classes)에서 많이 사용된다
-
상속을 해야만 해당 클래스에 접근할 수 있다는 얘기가 아니다!
-
Object 클래스는 모든 클래스의 부모 클래스다.
- 모든 타입을 받을 수 있는 최상위 객체
- 상속 관계와 다형성, 응용이 헷갈린다면 Object 클래스와 Object 클래스를 상속 받은 객체들을 지금껏 어떻게 활용했었는지 생각해보자.

-
장점
- 중복된 코드를 제거할 수 있다.
- 코드가 간결해진다.
- 재사용이 가능하다.
- 생산성이 증가한다.
-
부모 클래스의 생성자가 기본 생성자가 아닐 때 부모 생성자를 수동으로 선언해야 한다.
- 생성자 (Constructors)도 다른 생성자를 만들면 기본 생성자를 수동으로 만들어줘야 했다.
- 부모 생성자를 수동으로 선언한 후, 자식 클래스에서
super()로 생성자 호출을 해야 한다.
자식 클래스(하위 클래스, 서브 클래스)
부모 클래스(상위 클래스)의 필드와 메서드를 상속 받는 클래스
- 부모 클래스에 새로운 필드가 추가되면 자식 클래스에도 자동으로 해당 필드가 추가된 것처럼 동작한다.
- 부모 클래스의 멤버(필드와 메서드)만 상속, 생성자와 초기화 블록은 상속되지 않는다.
class 자식클래스이름 extends 부모클래스이름 {}
- 부모 클래스의 접근제한자가 private나 default로 설정된 멤버는 자식 클래스에서 상속은 받지만 접근할 수는 없다.
- 자식 클래스의 인스턴스를 생성하면, 해당 인스턴스에는 자식 클래스의 고유 멤버와 부모 클래스의 모든 멤버까지 포함된다.
class Test {
private String id; // 상속 불가
public int test; // 상속 가능
}
생성자 호출
-
자식 클래스를 생성하면 부모 클래스의 생성자를 먼저 방문하고, 그 다음 자식 클래스의 생성자를 방문한다.
- 자식 클래스의 생성자에서 부모 클래스의 생성자 호출을
super()로 명시하지 않아도 자식 클래스의 생성자가 호출되면 자동으로 호출된다. - 하지만 부모 클래스의 생성자가 기본 생성자(
ClassName())가 아닌 매개변수를 받는 생성자일 경우, 시스템이 자동으로 부모 클래스의 생성자를 만들 수 없기 때문에super(param1, param2, ...)를 자식 생성자에서 호출해야 한다.
- 자식 클래스의 생성자에서 부모 클래스의 생성자 호출을
-
부모 클래스의 멤버를 초기화하려면 자식 클래스의 생성자에서 부모 클래스의 생성자도
super()메서드로 호출해야 한다. -
super키워드는 인스턴스 메서드에만 참조 변수를 사용할 수 있고, 클래스 메서드에서는 사용할 수 없다.
// 부모클래스
class ParentClassName {
String test;
public ParentClassName() {
// 부모 클래스 기본 생성자
}
public testMethod() {
System.out.println("테스트 메서드");
}
}
// 부모클래스를 자식클래스로 확장
class ChildClassName extends ParentClassName {
String exam; // 자식 클래스의 고유 멤버
// 자식 클래스 생성자
// 시스템에서 실제로 상위 클래스의 생성자를 자동호출 해준다
public ChildClassName() {
System.out.pringln("자식클래스");
}
public ChildClassName(String test) {
// 상속받은 필드를 초기화
this.test = test;
}
}
public class InheritanceTest {
public static void main(String[] args) {
ChildClassName comic = new ChildClassName();
// 생성자 호출 시 자동으로 부모 생성자를 호출한다
// ---출력 내용---
// 테스트 메서드
// 자식클래스
}
}
부모 클래스의 멤버 호출
this처럼, 부모 클래스의 멤버는super를 사용하여 표시한다.super.부모클래스필드;,super.부모클래스메서드();
public Test {
public int id;
public Test() {
id = 10;
}
public void info() {
System.out.println("부모 클래스");
}
}
public Exam extends Test {
public int id;
public Exam() {
// 부모 클래스의 생성자 호출
super();
this.id = 20;
}
@Override
public void info() {
// 부모 클래스의 info() 호출
super.info();
System.out.println("자식 클래스");
}
}
상속 제한
- 자식 클래스는 여러 개의 부모를 동시에 상속 받을 수 없지만, 부모 클래스는 여러 자식 클래스에게 상속해줄 수 있다.
- Java에선 n차 상속을 받을 수 있다.
- 부모 클래스를 상속받은 자식 클래스를 다른 자식 클래스가 상속받을 수 있다.
class Test {
public String name;
}
class Exam extends Test {
public Exam() {}
}
class NewTest extends Test {
public NewTest() {}
}
상속의 종류
1. 단일 상속(Single Inheritance)
- 한 클래스가 다른 상위 클래스 하나만 상속 받는 방법이다.
public class Parent {}
public class Child extends Parent {}
2. 다층적 상속(Multilevel Inheritance)
- 하나의 상위 클래스를 상속 받은 자식 클래스를 또 다른 클래스가 상속 받는 방법이다.
public class Parent {}
public class Child extends Parent {}
public class Descent extends Child {}
3. 계층적 상속(Hierarchical Inheritance)
- 하나의 상위 클래스를 여러 개의 하위 클래스가 상속 받는 방법이다.
public class Person {}
public class Worker extends Person {}
public class Writer extends Person {}
4. 다중 상속(Multiple Inheritance) - Interface
- 하나의 클래스가 여러 개의 인터페이스로를 구현하는 방법이다.
- Java에선 자식 클래스가 여러 개의 부모 클래스를 가질 수 없기 때문에 인터페이스를 구현하는 방식으로 다중 상속을 구현할 수 있다.
public interface Parent1 {}
public interface Parent2 {}
public class Child implements Parent1, Parent2 {}
- 다이아몬드 문제 : 다중 상속 구조에서 두 개 이상의 부모가 공통의 조상 클래스를 상속 받고, 이 부모들을 동시에 상속 받을 때 발생하는 모호성 문제다.
- 자식 클래스에서 부모 클래스의 메서드를 호출할 때 공통 조상으로 인해 어느 부모의 메서드를 호출해야할 지 모른다.
- 따라서 Java에선 이런 문제를 방지하고자 클래스를 통한 다중 상속을 지원하지 않는다.
5. 하이브리드 상속(Hybrid Inheritance)
- 둘 이상의 상속 방법을 합쳐서 사용하는 방법이다.
- Java에서 다중 상속을 지원하지 않기 때문에 클래스 상속과 인터페이스 구현을 통한 복합적인 상속 구조를 만들 수 있다.
public class Parent {}
public interface Work {}
public interface Hobby {}
public class Child extends Parent implements Work, Hobby {}